package com.eltonkent.dashboard.util.gps;

import android.location.Location;
import android.util.Log;

public class GPSUtil {
	private static final double d2r = Math.PI / 180;

	public static double CalculateGreatCircleDistance(double lat1,
			double long1, double lat2, double long2, double radius) {
		return radius
				* Math.acos(Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1)
						* Math.cos(lat2) * Math.cos(long2 - long1));
	}

	public static double getDistanceBetweemInMiles(Location location1,
			Location location2) {
		return (getDistanceBetweenInKM(location1.getLatitude(), location1
				.getLongitude(), location2.getLatitude(), location2
				.getLongitude()) * 0.621371192);
	}

	/**
	 * Finds the distance between two GPS points in kilometers
	 * <p>
	 * Rounds the value off to two decimal places
	 * </p>
	 * 
	 * @param lat1
	 * @param long1
	 * @param lat2
	 * @param long2
	 * @return
	 */
	public static double getDistanceBetweenInKM(double lat1, double long1,
			double lat2, double long2) {
		double d = 0;
		try {
			double dlong = (long2 - long1) * d2r;
			double dlat = (lat2 - lat1) * d2r;
			double a = Math.pow(Math.sin(dlat / 2.0), 2) + Math.cos(lat1 * d2r)
					* Math.cos(lat2 * d2r) * Math.pow(Math.sin(dlong / 2.0), 2);
			double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
			d = 6372.797 * c;

		} catch (Exception e) {
			e.printStackTrace();
		}
		Log.d("DBA", "Raw distance " + d);
		return d;
	}

	public static double getDistanceBetweenInKM(Location location1,
			Location location2) {
		return getDistanceBetweenInKM(location1.getLatitude(), location1
				.getLongitude(), location2.getLatitude(), location2
				.getLongitude());
	}

	public static double getDistanceBetweenInMiles(double lat1, double long1,
			double lat2, double long2) {
		return getDistanceBetweenInKM(lat1, long1, lat2, long2) * 0.621371192;
	}

	/**
	 * Converts degree representation to NW,N,S etc.
	 * 
	 * @param degrees
	 * @return
	 */
	public static String getWindDirection(float degrees) {

		if (degrees >= 11.25 && degrees <= 33.75) {
			return "NNE";
		} else if (degrees > 33.75 && degrees <= 56.25) {
			return "NE";
		} else if (degrees > 56.25 && degrees <= 78.75) {
			return "ENE";
		} else if (degrees > 78.75 && degrees <= 101.25) {
			return "E";
		} else if (degrees > 101.25 && degrees <= 123.75) {
			return "ESE";
		} else if (degrees > 123.75 && degrees <= 146.25) {
			return "SE";
		} else if (degrees > 146.25 && degrees <= 168.75) {
			return "SSE";
		} else if (degrees > 168.75 && degrees <= 191.25) {
			return "S";
		} else if (degrees > 191.25 && degrees <= 213.75) {
			return "SSW";
		} else if (degrees > 213.75 && degrees <= 236.25) {
			return "SW";
		} else if (degrees > 236.25 && degrees <= 258.75) {
			return "WSW";
		} else if (degrees > 258.75 && degrees <= 281.25) {
			return "W";
		} else if (degrees > 281.25 && degrees <= 303.75) {
			return "WNW";
		} else if (degrees > 303.75 && degrees <= 326.25) {
			return "NW";
		} else if (degrees > 326.2 && degrees <= 348.75) {
			return "NNW";
		} else if (degrees > 348.75 && degrees < 11.25) {
			return "N";
		}
		return "U/K";
	}

	// calculate haversine distance for linear distance
	public static double haversine_km(double lat1, double long1, double lat2,
			double long2) {
		double dlong = (long2 - long1) * d2r;
		double dlat = (lat2 - lat1) * d2r;
		double a = Math.pow(Math.sin(dlat / 2.0), 2) + Math.cos(lat1 * d2r)
				* Math.cos(lat2 * d2r) * Math.pow(Math.sin(dlong / 2.0), 2);
		double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
		double d = 6367 * c;

		return d;
	}
}
